import util.*;

class util.Logger
{
	private var snappingBorder:Number = 10;
	
	// estrutura
	private var panel:MovieClip; // contem a toolbar e o textBoxes
	private var toolBar:MovieClip; // barra de ferramentas
	private var canvas:MovieClip;
	private var textBoxes:MovieClip; // contem as caixas de niveis
	
	private var width:Number = 200;
	private var height:Number = 200;
	
	private var minWidth:Number = 100;
	private var minHeight:Number = 50;

	private var state:String = "";
	public static var STATE_DEFAULT:String = "default";
	public static var STATE_MOVING:String = "moving";
	public static var STATE_MODIFYING:String = "modifiyng";
	public static var STATE_SET_HEIGHT_BOX_1:String = "setHeightBox1";
	public static var STATE_SET_HEIGHT_BOX_2:String = "setHeightBox2";
	public static var STATE_SET_HEIGHT_BOX_3:String = "setHeightBox3";
	
	private var panelXMouse = 0;
	private var panelYMouse = 0;
	
	// caixas de texto
	private static var text1:TextField;
	private static var text2:TextField;
	private static var text3:TextField;
	
	// caixas para diferenciar os nives de log
	private var textBox1:MovieClip;
	private var textBox2:MovieClip;
	private var textBox3:MovieClip;
	
	// alturas das caixas para diferenciar os nives de log
	private var textBox1Height:Number = null;
	private var textBox2Height:Number = null;
	private var textBox3Height:Number = null;
		
	// niveis de log
	public static var log1:Array;
	public static var log2:Array;
	public static var log3:Array;
	
	public static var line:Number = 0;
	private static var instance:Logger;
	
	private var textBoxNumber:Number = 3;
	
	private function Logger()
	{
		log1 = new Array();
		log2 = new Array();
		log3 = new Array();
	}
	
	public static function getInstance():Logger
	{
		if (instance == undefined)
		{
			instance = new Logger();
			return instance;
		}
		else
			return instance;
	}
	
	public static function start():Void
	{
		Logger.getInstance().createWindow();
	}
	
	public function createWindow():Void
	{
		panel = _root.createEmptyMovieClip("panel", 99999);

		drawToolBar();
		drawTextBoxes();
				
		Key.addListener(this);
	}
	
	private function drawTextBoxes():Void
	{
		textBoxes = panel.createEmptyMovieClip("textBoxes", panel.getNextHighestDepth());
		drawTextBox1();
		drawTextBox2();
		drawTextBox3();
		drawBModifySize();	
		drawBModifyHeightBox1();
		drawBModifyHeightBox2();
		drawBModifyHeightBox3();
	}
	
	public static function trace(object:Object, box:Number):Void
	{
		var lineSentence:String = (++line)+". "+object.toString() +"\n";
		if (box == 1)
		{
			log1.push(lineSentence);
			text1.text += lineSentence;
			text1.scroll += 10;
		}
		else if (box == 2)
		{
			log2.push(lineSentence);
			text2.text += lineSentence;
			text2.scroll += 10;
		}
		else
		{
			log3.push(lineSentence);
			text3.text += lineSentence;
			text3.scroll += 10;
		}
	}
		
	public function onKeyDown():Void
	{
		if (Key.getCode() == 76)
			panel._visible = !panel._visible;
	}

	private function drawToolBar():Void
	{
		toolBar = panel.createEmptyMovieClip("toolBar", panel.getNextHighestDepth());
		var heightBox:Number = 20;
		
		var box:MovieClip = toolBar.createEmptyMovieClip("box", toolBar.getNextHighestDepth());
		box.beginFill(0xCC0000, 100);
		box.lineStyle(1, 0xCC0000, 100);
		box.lineTo(width, 0);
		box.lineTo(width, heightBox);
		box.lineTo(0, heightBox);
		box.lineTo(0, 0);
		box.endFill();
		
		drawBClose();
		drawBMinimize();
		drawBClear();
		
		box.onPress = Delegate.create(this, onPressBToolBar);
	}
	
	private function drawTextBox1():Void
	{
		textBox1 = textBoxes.createEmptyMovieClip("textBox1", textBoxes.getNextHighestDepth());
		
		textBox1._y = toolBar._height;
		
		var heightBox:Number = textBox1Height;
		if (heightBox == null)
			heightBox = (height - toolBar._height)/textBoxNumber;
			
		var box:MovieClip = textBox1.createEmptyMovieClip("box1", textBox1.getNextHighestDepth());
		box.beginFill(0xFFFFFF, 80);
		box.lineStyle(1, 0xCC0000, 100);
		box.lineTo(width, 0);
		box.lineTo(width, heightBox);
		box.lineTo(0, heightBox);
		box.lineTo(0, 0);
		box.endFill();
		
		createTextField1();
	}
	
	private function drawTextBox2():Void
	{
		textBox2 = textBoxes.createEmptyMovieClip("textBox2", textBoxes.getNextHighestDepth());
		
		textBox2._y = toolBar._height + textBox1._height;
		
		var heightBox:Number = textBox2Height;
		if (heightBox == null)
			heightBox = (height - toolBar._height)/textBoxNumber;
		
		var box:MovieClip = textBox2.createEmptyMovieClip("box2", textBox2.getNextHighestDepth());
		box.beginFill(0xFFFFFF, 80);
		box.lineStyle(1, 0xCC0000, 100);
		box.lineTo(width, 0);
		box.lineTo(width, heightBox);
		box.lineTo(0, heightBox);
		box.lineTo(0, 0);
		box.endFill();
		
		createTextField2();
	}
	
	private function drawTextBox3():Void
	{
		textBox3 = textBoxes.createEmptyMovieClip("textBox3", textBoxes.getNextHighestDepth());
		
		textBox3._y = toolBar._height + textBox1._height + textBox2._height;
		
		var heightBox:Number = textBox3Height;
		if (heightBox == null)
			heightBox = (height - toolBar._height)/textBoxNumber;
		
		var box:MovieClip = textBox3.createEmptyMovieClip("box3", textBox3.getNextHighestDepth());
		box.beginFill(0xFFFFFF, 80);
		box.lineStyle(1, 0xCC0000, 100);
		box.lineTo(width, 0);
		box.lineTo(width, heightBox);
		box.lineTo(0, heightBox);
		box.lineTo(0, 0);
		box.endFill();
		
		createTextField3();
	}
	
	private function createTextField1():Void
	{
		var format:TextFormat = new TextFormat();
		format.font = "Verdana";
		format.size = 12;
		format.color = 0x000000;
		
		textBox1.createTextField("text1", textBox1.getNextHighestDepth(), 0, 0, textBox1._width, textBox1._height);
	  	text1 = textBox1["text1"];
	  	text1.html = true;
	  	text1.multiline = true;
	  	text1.wordWrap = true;
	  	text1.border = false;
	  	text1.setNewTextFormat(format);
	  	
	  	for (var i:Number = 0; i < log1.length; i++)
	  	{
	  		text1.text += log1[i];
	  		text1.scroll += 10;
	  	}
	}
	
	private function createTextField2():Void
	{
		var format:TextFormat = new TextFormat();
		format.font = "Verdana";
		format.size = 12;
		format.color = 0x000000;
		
		textBox2.createTextField("text2", textBox2.getNextHighestDepth(), 0, 0, textBox2._width, textBox2._height);
	  	text2 = textBox2["text2"];
	  	text2.html = true;
	  	text2.multiline = true;
	  	text2.wordWrap = true;
	  	text2.border = false;
	  	text2.setNewTextFormat(format);
	  	
	  	for (var i:Number = 0; i < log2.length; i++)
	  	{
	  		text2.text += log2[i];
	  		text2.scroll += 10;
	  	}
	}
	
	private function createTextField3():Void
	{
		var format:TextFormat = new TextFormat();
		format.font = "Verdana";
		format.size = 12;
		format.color = 0x000000;
		
		textBox3.createTextField("text3", textBox3.getNextHighestDepth(), 0, 0, textBox3._width, textBox3._height);
	  	text3 = textBox3["text3"];
	  	text3.html = true;
	  	text3.multiline = true;
	  	text3.wordWrap = true;
	  	text3.border = false;
	  	text3.setNewTextFormat(format);
	  	
	  	for (var i:Number = 0; i < log3.length; i++)
	  	{
	  		text3.text += log3[i];
	  		text3.scroll += 10;
	  	}
	}

	private function drawBClose():Void
	{
		var close:MovieClip = toolBar.createEmptyMovieClip("close", toolBar.getNextHighestDepth());
		close.beginFill(0xFFFFFF, 100);
		close.lineStyle(2, 0xCC0000, 100);
		var sizeButton:Number = 16;
		close.lineTo(sizeButton, 0);
		close.lineTo(sizeButton, sizeButton);
		close.lineTo(0, sizeButton);
		close.lineTo(0, 0);
		close.moveTo(3, 3);
		close.lineTo(sizeButton - 3, sizeButton - 3);
		close.moveTo(sizeButton - 3, 3);
		close.lineTo(3, sizeButton - 3);
		close.endFill();
		var border:Number = 2;
		close._x = width - (sizeButton + border);
		close._y = border;
		
		close.onRelease = Delegate.create(this, onReleaseBClose);
	}
	
	private function drawBModifySize():Void
	{
		var modifySize:MovieClip = textBoxes.createEmptyMovieClip("modifySize", textBoxes.getNextHighestDepth());
		modifySize.beginFill(0xCC0000, 50);
		modifySize.lineStyle(0, 0x000000, 0);
		var sizeButton:Number = 16;
		modifySize.moveTo(sizeButton, 0);
		modifySize.lineTo(sizeButton, sizeButton);
		modifySize.lineTo(0, sizeButton);
		modifySize.endFill();
		
		modifySize._x = width - (sizeButton);
		modifySize._y = textBoxes._height - (sizeButton);
		
		modifySize.onPress = Delegate.create(this, onPressBModifySize);
	}
	
	private function drawBModifyHeightBox1():Void
	{
		var modifyHeight:MovieClip = textBoxes.createEmptyMovieClip("modifyHeightBox1", textBoxes.getNextHighestDepth());
		modifyHeight.beginFill(0xCC0000, 50);
		modifyHeight.lineStyle(0, 0x000000, 0);
		var sizeButton:Number = 16;
		modifyHeight.moveTo(sizeButton/2, 0);
		modifyHeight.lineTo(sizeButton, sizeButton/2);
		modifyHeight.lineTo(sizeButton/2, sizeButton);
		modifyHeight.lineTo(0, sizeButton/2);
		modifyHeight.lineTo(sizeButton/2, 0);
		modifyHeight.endFill();
		
		modifyHeight._x = (sizeButton/2) * -1;
		modifyHeight._y = (textBox1._height+textBox1._y) - (sizeButton/2);
		
		modifyHeight.onPress = Delegate.create(this, onPressBModifyHeightBox1);
	}
	
	private function drawBModifyHeightBox2():Void
	{
		var modifyHeight:MovieClip = textBoxes.createEmptyMovieClip("modifyHeightBox2", textBoxes.getNextHighestDepth());
		modifyHeight.beginFill(0xCC0000, 50);
		modifyHeight.lineStyle(0, 0x000000, 0);
		var sizeButton:Number = 16;
		modifyHeight.moveTo(sizeButton/2, 0);
		modifyHeight.lineTo(sizeButton, sizeButton/2);
		modifyHeight.lineTo(sizeButton/2, sizeButton);
		modifyHeight.lineTo(0, sizeButton/2);
		modifyHeight.lineTo(sizeButton/2, 0);
		modifyHeight.endFill();
		
		modifyHeight._x = (sizeButton/2) * -1;
		modifyHeight._y = (textBox2._height+textBox2._y) - (sizeButton/2);
		
		modifyHeight.onPress = Delegate.create(this, onPressBModifyHeightBox2);
	}
	
	private function drawBModifyHeightBox3():Void
	{
		var modifyHeight:MovieClip = textBoxes.createEmptyMovieClip("modifyHeightBox3", textBoxes.getNextHighestDepth());
		modifyHeight.beginFill(0xCC0000, 50);
		modifyHeight.lineStyle(0, 0x000000, 0);
		var sizeButton:Number = 16;
		modifyHeight.moveTo(sizeButton/2, 0);
		modifyHeight.lineTo(sizeButton, sizeButton/2);
		modifyHeight.lineTo(sizeButton/2, sizeButton);
		modifyHeight.lineTo(0, sizeButton/2);
		modifyHeight.lineTo(sizeButton/2, 0);
		modifyHeight.endFill();
		
		modifyHeight._x = (sizeButton/2) * -1;
		modifyHeight._y = (textBox3._height+textBox3._y) - (sizeButton/2);
		
		modifyHeight.onPress = Delegate.create(this, onPressBModifyHeightBox3);
	}
	
	private function drawBMinimize():Void
	{
		var minimize:MovieClip = toolBar.createEmptyMovieClip("minimize", toolBar.getNextHighestDepth());
		minimize.beginFill(0xFFFFFF, 100);
		minimize.lineStyle(2, 0xCC0000, 100);
		var sizeButton:Number = 16;
		minimize.lineTo(sizeButton, 0);
		minimize.lineTo(sizeButton, sizeButton);
		minimize.lineTo(0, sizeButton);
		minimize.lineTo(0, 0);
		minimize.moveTo(3, sizeButton-3);
		minimize.lineTo(sizeButton/2, sizeButton-3);
		minimize.endFill();
		var border:Number = 2;
		minimize._x = width - ((sizeButton + border) *2);
		minimize._y = border;
		
		minimize.onRelease = Delegate.create(this, onReleaseBMinimize);
	}
	
	private function drawBClear():Void
	{
		var clear:MovieClip = toolBar.createEmptyMovieClip("clear", toolBar.getNextHighestDepth());
		var widthButton:Number = 45;
		var heightButton:Number = 16;
		
		clear.beginFill(0xFFFFFF, 100);
		clear.lineStyle(2, 0xCC0000, 100);
		clear.lineTo(widthButton, 0);
		clear.lineTo(widthButton, heightButton);
		clear.lineTo(0, heightButton);
		clear.lineTo(0, 0);
		clear.endFill();
		var border:Number = 2;
		clear._x = border;
		clear._y = border;
		
		var format:TextFormat = new TextFormat();
		format.font = "Verdana";
		format.size = 10;
		format.color = 0xCC0000;
		
		clear.createTextField("limpar", clear.getNextHighestDepth(), 0, 0, widthButton, heightButton);
	  	var clearText:TextField = TextField(clear["limpar"]);
	  	clearText.border = false;
	  	clearText.setNewTextFormat(format);
	  	clearText.text = "Limpar";

		clear.onRelease = Delegate.create(this, onReleaseBClear);
	}
	
	public function onReleaseBClose():Void
	{
		panel.removeMovieClip();
	}
	
	public function onReleaseBClear():Void
	{
		text1.htmlText = "";
		log1 = new Array();
		text2.htmlText = "";
		log2 = new Array();
		text3.htmlText = "";
		log3 = new Array();
	}
	
	public function onPressBModifySize():Void
	{
		state = STATE_MODIFYING;
		drawCanvas();
		Mouse.addListener(this);
	}
	
	public function onPressBModifyHeightBox1():Void
	{
		state = STATE_SET_HEIGHT_BOX_1;
		drawLine();
		Mouse.addListener(this);
	}
	
	public function onPressBModifyHeightBox2():Void
	{
		state = STATE_SET_HEIGHT_BOX_2;
		drawLine();
		Mouse.addListener(this);
	}
	
	public function onPressBModifyHeightBox3():Void
	{
		state = STATE_SET_HEIGHT_BOX_3;
		drawLine();
		Mouse.addListener(this);
	}
	
	public function onReleaseBMinimize():Void
	{
		textBoxes._visible = !textBoxes._visible;
	}

	public function onPressBToolBar():Void
	{
		state = STATE_MOVING;

		drawCanvas();
		Mouse.addListener(this);
	}
	
	// evento chamado quando eu solto o botao do mouse e as alteracoes visuais devem ser efetivadas
	public function onMouseUp():Void
	{
		Mouse.removeListener(this);
		
		if (state == STATE_MOVING)
		{
			if (canvas._x + panelXMouse < snappingBorder)
				panel._x = 0;
	    	else if ((canvas._x + panelXMouse) + panel._width > Stage.width - snappingBorder)
	    		panel._x = Stage.width - panel._width;
	    	else
	    		panel._x = canvas._x + panelXMouse;
	    	
	    	if (canvas._y + panelYMouse < snappingBorder)
	    		panel._y = 0;
	    	else if ((canvas._y + panelYMouse) + panel._height > Stage.height - snappingBorder)
	    		panel._y = Stage.height - panel._height;
			else
				panel._y = canvas._y + panelYMouse;
		}
		else if (state == STATE_MODIFYING)
		{
			// quando modificado o tamanho no panel todas as caixas de texto passam a ter a mesma altura
			textBox1Height = null; 
			textBox2Height = null;
			textBox3Height = null;
			
			if (_root._xmouse > Stage.width)
				width = Stage.width - panel._x;
			else
				width = canvas._width;
			
			if (_root._ymouse > Stage.height)
				height = Stage.height - panel._y;
			else
			  	height = canvas._height;
	    	
	    	resetPanel();
	    }
	    
	    else if (state == STATE_SET_HEIGHT_BOX_1)
		{
			textBox1Height = (canvas._y - panel._y - textBoxes._y) - textBox1._y;
			resetPanel();
			height = panel._height;
		}
		
		else if (state == STATE_SET_HEIGHT_BOX_2)
		{
			textBox2Height = textBoxes._ymouse - textBox2._y;
			resetPanel();
			
			height = panel._height;
		}
		
		else if (state == STATE_SET_HEIGHT_BOX_3)
		{
			textBox3Height = textBoxes._ymouse - textBox3._y;
			resetPanel();
			
			height = panel._height;
		}
		
		canvas.removeMovieClip();
		state = STATE_DEFAULT;
	}
	
	private function resetPanel():Void
	{
		toolBar.removeMovieClip();
	    textBoxes.removeMovieClip();
	    	
	    drawToolBar();
	    drawTextBoxes();
	}
	
	// evento chamado quando estou segurando algo com o mouse, e arrastando pela tela
	public function onMouseMove():Void
	{
		if (state == STATE_MOVING)
		{
			canvas._x = _root._xmouse;
	    	canvas._y = _root._ymouse;
		}
		else if (state == STATE_MODIFYING)
		{
			if (panel._xmouse >= minWidth && panel._ymouse >= minHeight)
			{
				canvas.removeMovieClip();
				drawCanvas(panel._xmouse, panel._ymouse);
			}
		}
		else if (state == STATE_SET_HEIGHT_BOX_1 && textBoxes._ymouse > textBox1._y + 10
		 		|| state == STATE_SET_HEIGHT_BOX_2 && textBoxes._ymouse > textBox2._y + 10
		 		|| state == STATE_SET_HEIGHT_BOX_3 && textBoxes._ymouse > textBox3._y + 10)
		{
			canvas._y = _root._ymouse;
		}
    }
    
    private function drawCanvas(canvasWidth:Number, canvasHeight:Number):Void
    {
    	if (!canvasWidth)
    		canvasWidth = width;
    	
    	if (!canvasHeight)
    		canvasHeight = height;
    		
    	canvas = _root.createEmptyMovieClip("canvas", _root.getNextHighestDepth());
		canvas.beginFill(0xFFFFFF, 50);
		canvas.lineStyle(1, 0x000000, 50);
		
		panelXMouse = -1 * panel._xmouse;
		panelYMouse = -1 * panel._ymouse;
		canvas.moveTo(panelXMouse, panelYMouse);
		canvas.lineTo(canvasWidth + panelXMouse, panelYMouse);
		canvas.lineTo(canvasWidth + panelXMouse, canvasHeight + panelYMouse);
		canvas.lineTo(panelXMouse, canvasHeight + panelYMouse);
		canvas.lineTo(panelXMouse, panelYMouse);
		canvas.endFill();
		
		canvas._x = _root._xmouse;
	    canvas._y = _root._ymouse;
    }
    
    private function drawLine():Void
    {
    	canvas = _root.createEmptyMovieClip("canvas", _root.getNextHighestDepth());
		canvas.beginFill(0xFFFFFF, 50);
		canvas.lineStyle(1, 0x000000, 50);
		
		//panelYMouse = -1 * panel._ymouse;
		canvas.moveTo(0, 0);
		canvas.lineTo(Stage.width, 0);
		canvas.lineTo(Stage.width, 2);
		canvas.lineTo(0, 2);
		canvas.lineTo(0, 0);
		canvas.endFill();
		
		canvas._y = _root._ymouse;
    }
}